#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>

/*次线程的个数*/
#define SECON_PTH_NUMS 	2

/*次线程退出标志*/
#define PTH_EXIT 		-1

/*线程的参数结构体*/
typedef struct pthread_arg{
	int fd;			/*线程操作的文件描述符*/
	int pthno;		/*自定义的线程编号*/
	pthread_t tid;	/*线程ID*/
}ptharg;


/*全局变量结构体*/
struct global_var{
	ptharg pthargs[SECON_PTH_NUMS];			/*线程参数*/
	int pth_exit_flg[SECON_PTH_NUMS];	 	/* 每个元素存放对应编号线程的退出状态 */
}glbva;


/*报错函数*/
void print_err(char *str, int line, int err_no)
{
	printf("%d,%s:%s",line,str,strerror(err_no));
	exit(-1);
}

/* 定时到后的处理函数 */
void signal_fun(int signal)
{
	int i = 0;

	if(SIGALRM == signal)
	{
		for(i=0;i<SECON_PTH_NUMS;i++)
		{
			pthread_cancel(glbva.pthargs[i].tid);
			//glbva.pth_exit_flg[i] = PTH_EXIT;		/*设置退出状态*/
		}
	}
}


/*线程函数*/
void * pth_fun(void *pth_arg)
{
	int fd = ((ptharg *)(pth_arg))->fd;
	pthread_t tid = ((ptharg *)pth_arg)->tid;
	int pthno = ((ptharg *)pth_arg)->pthno;

	printf("pthno=%d , tid =%lu\n",pthno,tid);

	printf("pthno=%d , tid2 =%lu\n",pthno,pthread_self());

	pthread_detach(pthread_self());/*线程把自己分离出去*/

	while(1)
	{
		write(fd,"hello ",6);
		write(fd,"world\n",6);
		//printf("######\n");

		/*检测退出状态*/
		if(glbva.pth_exit_flg[pthno] == PTH_EXIT)
		{
			break; /*跳出死循环，线程执行完*/
		}
	}
	//return NULL;
	//pthread_exit(NULL);
	pthread_exit((void *)10);
} 


int main(void)
{
	int ret = 0;
	int i = 0;
	int fd =0;
	

	fd = open("./file",O_RDWR|O_CREAT|O_TRUNC,0664);
	if(fd == -1) print_err("open ",__LINE__,fd);
	
	for(i=0;i<SECON_PTH_NUMS;i++)
	{
		glbva.pthargs[i].fd = fd;
		glbva.pthargs[i].pthno = i;

		ret = pthread_create(&glbva.pthargs[i].tid,NULL,pth_fun,&glbva.pthargs[i]);
		if(ret != 0) print_err("pthread_create",__LINE__,ret);

		//pthread_detach(glbva.pthargs[i].tid);
	}
	
	
	printf("main tid = %lu\n",pthread_self());	/* 获取主线程的tid */

	/*定时3秒，时间到后，取消次线程*/
	signal(SIGALRM,signal_fun);
	alarm(3);/*定时3秒*/


	#if 0
	void *retval = NULL;
	for(i=0;i<SECON_PTH_NUMS;i++)
	{
		/*阻塞等待次线程结束，回收次线程资源并通过第二个参数接收返回值*/
		pthread_join(glbva.pthargs[i].tid,&retval);
		printf("@@ %ld\n",(long int)retval);
	}
	#endif

	while(1)
	{
		write(fd,"hello ",6);
		write(fd,"world\n",6);
	}
	
	return 0;
}






































